home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume89
/
iff
/
if2sixel.1
next >
Wrap
Internet Message Format
|
1989-05-09
|
21KB
Path: xanth!indri!ames!oliveb!sun!swap!page
From: page%swap@Sun.COM (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v89i120: iff2sixel - convert iff files to dec sixel format
Message-ID: <103774@sun.Eng.Sun.COM>
Date: 9 May 89 05:00:30 GMT
Sender: news@sun.Eng.Sun.COM
Lines: 778
Approved: page@sun.com
Submitted-by: kennedy%wwpacs@dupont.com (Tony Kennedy)
Posting-number: Volume 89, Issue 120
Archive-name: iff/iff2sixel.1
Here's a program I wrote to convert IFF pictures to DEC Sixels. You
can now display IFF files on VT240s, VT241s, VT340s and the like.
[binary not available; use your favorite compiler. ..bob]
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# ReadMe
# iff2sixel.c
# This is archive 1 of a 1-part kit.
# This archive created: Mon May 8 21:54:31 1989
echo "extracting ReadMe"
sed 's/^X//' << \SHAR_EOF > ReadMe
XHi there,
X
XHere's the program. It's got a few limitations. It NEEDS a 16 color
Xfile for a 340 (you can use fewer that 16 but not more), or 4 colors
Xfor a 240. I ran it with HAM converted to hires interlace with
XPixmate and they look great. The best results are the 16 color hires
Xinterlaced picts.
X
XLet me know if you find this program useful and if there are any bugs.
XAlso please let me know what environment/compiler/linker you used (for
Xfuture versions)
X
X Enjoy...
X ...Tony
SHAR_EOF
echo "extracting iff2sixel.c"
sed 's/^X//' << \SHAR_EOF > iff2sixel.c
X/*****************************************************************************/
X/*
X Program : IFF2SIXEL.C
X
X Author : Tony Kennedy
X Internet address: kennedam%wwps@dupont.com@relay.cs.net
X
X Purpose : This program takes a AMIGA IFF ILBM file and converts
X it to a SIXEL file to be displayed on DIGITAL EQUIPMENT
X CORP. VT240, VT241, VT340 terminals.
X
X This version will handle only 16 colors for a VT340 and
X 4 colors for a VT240. It does no color compression, so
X all input files must be 16 colors or less for a 340,
X 4 colors or less for a 240.
X
X If the display is a VT240/241 then the resolution
X is set to 640X200. If it's a 340 then the res is 640X400.
X
X I tried to make it a generic as possible so you can
X compile it under what ever environment you please.
X If you do it under VMS you will need to define IFF2SIXEL
X as a foreign command i.e. $ iff2sixel :== $mydir:iff2sixel
X otherwise you can't use command line args.
X
X Usage : iff2sixel <input_file> <output_file> <VT240 | VT340>
X
X Comments : This program is Freely Distributable. You may
X use it for any non-commercial uses.
X (If anybody hacks at this please send me a copy.)
X
X Acknowledgements : Thanks to...
X
X Carter Brock for the SHOW_IFF program I used
X to figure out how to read an IFF file.
X
X Mark Thompson and Steve Berry for the IFF2SUN
X program I used to figure out how to interpret
X the bitplanes.
X
X Barry Young for his help with SIXEL formats.
X
X Daniel Jay Barrett for his switching bytes
X hacks.
X
X Limitations : This won't do HAM or Halfbrite. When I figure them out
X I'll put that in too.
X Won't do any color compression.
X
X
X Versions: Revisions :
X
X 1.0 3/1/89 Original program.
X
X*/
X/*****************************************************************************/
X
X#include <stdio.h>
X#include <math.h>
X
X#define Sixel_base 63
X#define DCS 144
X#define ST 156
X#define QUOTE 34
X
X#define LoRes 1
X#define LoLace 2
X#define HiRes 3
X#define HiLace 4
X
X#define VT240_LoRes 1
X#define VT240_LoLace 2
X#define VT240_HiRes 3
X#define VT240_HiLace 4
X#define VT340_LoRes 5
X#define VT340_LoLace 6
X#define VT340_HiRes 7
X#define VT340_HiLace 8
X
X typedef unsigned char ID_type[4];
X struct ChunkType
X {
X ID_type Ident ;
X long ChunkSize ;
X } ;
X struct ChunkType chunk ;
X
X typedef struct
X {
X unsigned char red, green, blue;
X } ColorRegType;
X
X unsigned char BitPlaneArray[400][6][128]; /* vert posit, plane, width posit*/
X unsigned char PixelArray[400][640]; /* vert posit, horiz posit */
X int SixelLine[16][640][80]; /* color,horizontal posit, row.*/
X int vert, horz, s_vert, v_bit;
X
X/********************************************************************
X
X This function decompresses the IFF file. I got the algorithm
X from Mark and Steve who got it from Leo (The Great Caped One).
X
X********************************************************************/
X
X int decompress_planes(nplanes,width,height,inp_file)
X
X unsigned short nplanes,width,height;
X FILE *inp_file;
X
X {
X long h,p,count,BytesPerRow;
X char len;
X unsigned char byte;
X
X for (h=0;h<height;h++)
X {
X for (p=0;p<nplanes;p++)
X {
X count = 0;
X BytesPerRow=width/8;
X while(BytesPerRow>0)
X {
X if ((len = getc(inp_file)) >= 0)
X {
X BytesPerRow -= ++len;
X fread(&BitPlaneArray[h][p][count],len,1,inp_file);
X count += len;
X }
X else
X if (len < 0)
X {
X len = -len + 1;
X BytesPerRow -= len;
X byte = getc(inp_file);
X while (--len >= 0)
X BitPlaneArray[h][p][count++] = byte;
X }
X }
X if (BytesPerRow) printf("Compression is corrupt.\n");
X }
X }
X }
X
X/********************************************************************
X
X Since the VAX reads shorts and longs backwards we've got to
X flip them around...
X
X********************************************************************/
X
X#ifdef VAX
X
Xshort flip_byte_short(s)
X
X short s;
X {
X short hib,lob;
X
X lob = (s & 255);
X hib = ((s >> 8) & 255);
X return ((lob << 8) + hib);
X }
X
Xlong flip_bytes_long(l)
X
X long l;
X {
X short low,hiw;
X
X low = (l & 65535);
X hiw = ((l >> 16) & 65535);
X return ( ((flip_byte_short(low) << 16) + flip_byte_short(hiw)));
X }
X#endif
X
X/********************************************************************
X
X Convert a string to upper case.
X
X********************************************************************/
X
Xchar *upcase(str)
X
X char *str;
X
X {
X int len, i;
X
X i=0;
X len=strlen(str);
X while(i != len)
X {
X str[i]=toupper(str[i]);
X i++;
X }
X return str;
X }
X
X/********************************************************************
X
X Double the width of the Pixel Array.
X
X********************************************************************/
X
X short double_width(width,height)
X
X short width,height;
X
X {
X short h,w;
X for (h=0;h<height;h++)
X {
X for (w=width-1;w>=0;w--)
X {
X PixelArray[h][w * 2] = PixelArray[h][w];
X PixelArray[h][(w * 2)+1] = PixelArray[h][w];
X }
X }
X return (width * 2);
X }
X
X/********************************************************************
X
X Double the height of the Pixel array.
X
X********************************************************************/
X
X short double_height(width,height)
X
X short width,height;
X
X {
X short h,w;
X for (w=0;w<width;w++)
X for (h=height-1;h>=0;h--)
X {
X PixelArray[h * 2][w]=PixelArray[h][w];
X PixelArray[(h * 2)+1][w]=PixelArray[h][w];
X }
X return (height * 2);
X }
X
X/********************************************************************
X
X Halve the height of the Pixel Array. This is gonna make the
X picture look pretty ugly if you ask me. Only gets done if a
X picture for a VT240 from an interlace IFF file is being
X generated.
X
X********************************************************************/
X
Xshort halve_height(width,height)
X
X short width,height;
X
X {
X short h,w;
X for (h=0;h<height;h++)
X for (w=0;w<=width;w++)
X PixelArray[h][w]=PixelArray[(h * 2)][w];
X
X return (height/2);
X }
Xmain (argc,argv)
X
X int argc;
X char **argv[];
X
X {
X long num_colors;
X int stat;
X long posit,h,w,p,i,j,k,l,m,pixel;
X long w_pos,cnt_100,cnt_10,cnt_1,rep_cnt;
X char ch, outline[700];
X unsigned char color;
X char *term;
X char term_type[5];
X char *input_file;
X char *output_file;
X FILE *outf,*inf;
X char start_sixel = DCS;
X char end_sixel = ST;
X char quote = QUOTE;
X int convert_mode = 0;
X int resolution;
X
X struct BitMapHeaderType
X {
X unsigned short width, height;
X short org_x, org_y;
X unsigned char NumPlanes, Mask, Compression, pad;
X unsigned short TransColor;
X unsigned char X_Asp, Y_Asp;
X unsigned short PageWid, PageHeight;
X } ;
X struct BitMapHeaderType bmhd;
X
X ColorRegType CMap[16];
X
X/*********************************************************************
X
X First, get all the needed info from the user...
X
X Input file, Output file, Type of terminal to create a file for.
X
X*********************************************************************/
X switch (argc)
X {
X case 1 :
X printf("Input File Name : ");
X scanf ("%s",&input_file);
X printf("Output File Name : ");
X scanf("%s",&output_file);
X printf("\nThis will generate SIXELS for a VT240 @ 640x240.\n");
X printf("or a VT340 @ 640x480.\n");
X printf("Enter VT240 or VT340 : ");
X scanf("%s",&term_type);
X inf = fopen(&input_file,"r");
X outf = fopen(&output_file,"w");
X term = &term_type;
X break;
X
X case 2 :
X
X printf("Output File Name : ");
X scanf("%s",&output_file);
X printf("\nThis will generate SIXELS for a VT240 @ 640x240.\n");
X printf("or a VT340 @ 640x480.\n");
X printf("Enter VT240 or VT340 : ");
X scanf("%s",&term_type);
X inf = fopen(argv[1],"r");
X outf = fopen(&output_file,"w");
X term = &term_type;
X break;
X
X case 3 :
X
X printf("\nThis will generate SIXELS for a VT240 @ 640x240.\n");
X printf("or a VT340 @ 640x480.\n");
X printf("Enter VT240 or VT340 : ");
X scanf("%s",&term_type);
X inf = fopen(argv[1],"r");
X outf = fopen(argv[2],"w");
X term = &term_type;
X break;
X
X case 4 :
X
X inf = fopen(argv[1],"r");
X outf = fopen(argv[2],"w");
X term = argv[3];
X
X }
X
X if (outf == NULL) {
X printf("Output can't be opened.\n");
X exit(0); }
X
X if (inf == NULL) {
X printf("Input file can't be opened.\n");
X exit(0); }
X
X
X/*********************************************************************
X
X Ok. Now read in the IFF file...
X
X*********************************************************************/
X
X
X stat=fread(chunk.Ident,4,1,inf);
X if (stat == -1)
X {
X printf("Error reading file.\n");
X stat=close(inf) ; stat=close(outf);
X exit(0);
X }
X
X
X while (strncmp(chunk.Ident,"FORM",4) !=0)
X stat=fread(chunk.Ident,4,1,inf);
X
X if (strncmp(chunk.Ident,"FORM",4) != 0)
X {
X printf("Error, not a FORM file.\n");
X stat=close(inf); stat=close(outf);
X exit(0);
X }
X
X stat=fread(&chunk.ChunkSize,4,1,inf);
X
X stat=fread(chunk.Ident,4,1,inf);
X
X while (strncmp(chunk.Ident,"ILBM",4) !=0)
X stat=fread(chunk.Ident,4,1,inf);
X
X if (strncmp(chunk.Ident, "ILBM",4) !=0)
X
X {
X printf("Error Not an ILBM file.\n");
X stat=close(inf); stat=close(outf);
X exit(0);
X }
X stat=fread(chunk.Ident,4,1,inf);
X
X while (strncmp(chunk.Ident,"BMHD",4) !=0)
X stat=fread(chunk.Ident,4,1,inf);
X
X if (strncmp(chunk.Ident, "BMHD",4) !=0)
X {
X printf("Error can't find Bit Map Header.\n");
X stat=close(inf); stat=close(outf);
X exit(0);
X }
X
X stat=fread(&chunk.ChunkSize,4,1,inf);
X stat=fread(chunk.Ident,2,1,inf);
X bmhd.width = *((short *)chunk.Ident);
X stat=fread(chunk.Ident,2,1,inf);
X bmhd.height = *((short *)chunk.Ident);
X stat=fread(chunk.Ident,2,1,inf);
X bmhd.org_x = *((short *)chunk.Ident);
X stat=fread(chunk.Ident,2,1,inf);
X bmhd.org_y = *((short *)chunk.Ident);
X stat=fread(chunk.Ident,1,1,inf);
X bmhd.NumPlanes = *((char *)chunk.Ident);
X stat=fread(chunk.Ident,1,1,inf);
X bmhd.Mask = *((char *)chunk.Ident);
X stat=fread(chunk.Ident,1,1,inf);
X bmhd.Compression = *((char *)chunk.Ident);
X stat=fread(chunk.Ident,1,1,inf);
X stat=fread(chunk.Ident,2,1,inf);
X bmhd.TransColor = *((short *)chunk.Ident);
X stat=fread(chunk.Ident,1,1,inf);
X bmhd.X_Asp = *((char *)chunk.Ident);
X stat=fread(chunk.Ident,1,1,inf);
X bmhd.Y_Asp = *((char *)chunk.Ident);
X stat=fread(chunk.Ident,2,1,inf);
X bmhd.PageWid = *((short *)chunk.Ident);
X stat=fread(chunk.Ident,2,1,inf);
X bmhd.PageHeight = *((short *)chunk.Ident);
X
X if (stat == -1)
X {
X printf("Error failed to get Bit Map information.\n");
X stat=close(inf); stat=close(outf);
X exit(0);
X }
X
X
X stat=fread(chunk.Ident,4,1,inf);
X
X while (strncmp(chunk.Ident,"CMAP",4) !=0)
X stat=fread(chunk.Ident,4,1,inf);
X
X if (strncmp(chunk.Ident,"CMAP",4) !=0)
X {
X printf("Error can't find Color Map.\n");
X stat=close(inf); stat=close(outf);
X exit(0);
X }
X stat=fread(&num_colors,4,1,inf);
X
X#ifdef VAX
X
X bmhd.width=flip_byte_short(bmhd.width);
X bmhd.height=flip_byte_short(bmhd.height);
X bmhd.org_x=flip_byte_short(bmhd.org_x);
X bmhd.org_y=flip_byte_short(bmhd.org_y);
X bmhd.TransColor=flip_byte_short(bmhd.TransColor);
X bmhd.PageWid=flip_byte_short(bmhd.PageWid);
X bmhd.PageHeight=flip_byte_short(bmhd.PageHeight);
X num_colors=flip_bytes_long(num_colors);
X
X#endif
X
X/********************************************************************
X
X define conversion mode
X
X********************************************************************/
X
X if ((bmhd.width==320)&&(bmhd.height==200)) resolution = LoRes;
X if ((bmhd.width==320)&&(bmhd.height==400)) resolution = LoLace;
X if ((bmhd.width==640)&&(bmhd.height==200)) resolution = HiRes;
X if ((bmhd.width==640)&&(bmhd.height==400)) resolution = HiLace;
X
X
X if ((strcmp(upcase(term),"VT240",5) == 0) &&
X (resolution==LoRes)) convert_mode=VT240_LoRes;
X
X if ((strcmp(upcase(term),"VT240",5) == 0) &&
X (resolution==LoLace)) convert_mode=VT240_LoLace;
X
X if ((strcmp(upcase(term),"VT240",5) == 0) &&
X (resolution==HiRes)) convert_mode=VT240_HiRes;
X
X if ((strcmp(upcase(term),"VT240",5) == 0) &&
X (resolution==HiLace)) convert_mode=VT240_HiLace;
X
X if ((strcmp(upcase(term),"VT340",5) == 0) &&
X (resolution==LoRes)) convert_mode=VT340_LoRes;
X
X if ((strcmp(upcase(term),"VT340",5) == 0) &&
X (resolution==LoLace)) convert_mode=VT340_LoLace;
X
X if ((strcmp(upcase(term),"VT340",5) == 0) &&
X (resolution==HiRes)) convert_mode=VT340_HiRes;
X
X if ((strcmp(upcase(term),"VT340",5) == 0) &&
X (resolution==HiLace)) convert_mode=VT340_HiLace;
X
X if (!convert_mode) {
X printf("IFF picture is an irregular size.\n");
X close(inf);
X close(outf);
X exit(0);
X }
X
X
X num_colors=num_colors/3;
X stat=fread(CMap,(num_colors * 3),1,inf);
X
X if ( (num_colors > 16) ||
X ((num_colors > 4) && (strcmp(upcase(term),"VT240",5) == 0))
X )
X
X {
X printf("File has too many colors for this conversion.\n");
X close(inf);
X close(outf);
X exit(0);
X }
X
X/********************************************************************
X
X Skip everything till we find the BODY.
X
X********************************************************************/
X
X stat=fread(chunk.Ident,4,1,inf);
X while (strncmp(chunk.Ident,"BODY",4) !=0)
X stat=fread(chunk.Ident,4,1,inf);
X
X
X stat=fread(chunk.Ident,4,1,inf); /* body length */
X
X
X/********************************************************************
X
X Now read the bit planes in.
X
X********************************************************************/
X
X if (bmhd.Compression == 1)
X decompress_planes(bmhd.NumPlanes,bmhd.width,bmhd.height,inf);
X else
X
X for (h = 0;h<bmhd.height;h++)
X for (p = 0;p<bmhd.NumPlanes;p++)
X {
X for (w = 0;w<bmhd.width/8;w++)
X {
X if (feof(inf)) continue;
X read(inf,BitPlaneArray[h][p][w],1);
X }
X }
X close(inf);
X
X/********************************************************************
X
X Translate bit planes to pixel color values.
X
X********************************************************************/
X
X for (h = 0;h<bmhd.height;h++)
X {
X w_pos = 0;
X for (w=0;w<bmhd.width/8;w++)
X {
X pixel = 0;
X for (i=7;i>=0;i--)
X {
X
X for (p=0;p<bmhd.NumPlanes;p++)
X pixel = ((((1 << i) & BitPlaneArray[h][p][w])>>i)<<p)|pixel;
X
X PixelArray[h][w_pos++] = (char)(pixel & 0x1f);
X pixel = 0;
X }
X }
X }
X
X/********************************************************************
X
X Convert to screen size.
X
X********************************************************************/
X
X switch(convert_mode)
X
X {
X case VT240_LoRes :
X bmhd.width = double_width(bmhd.width,bmhd.height);
X break;
X
X case VT240_LoLace :
X bmhd.height = halve_height(bmhd.width,bmhd.height);
X bmhd.width = double_width(bmhd.width,bmhd.height);
X break;
X
X case VT240_HiRes :
X break;
X
X case VT240_HiLace :
X bmhd.height = halve_height(bmhd.width,bmhd.height);
X break;
X
X case VT340_LoRes :
X bmhd.width = double_width(bmhd.width,bmhd.height);
X bmhd.height = double_height(bmhd.width,bmhd.height);
X break;
X
X case VT340_LoLace :
X bmhd.width = double_width(bmhd.width,bmhd.height);
X break;
X
X case VT340_HiRes :
X bmhd.height = double_height(bmhd.width,bmhd.height);
X break;
X
X case VT340_HiLace :
X break;
X
X }
X
X/********************************************************************
X
X Convert Pixels to Sixels.
X
X********************************************************************/
X
X vert=bmhd.height;
X horz=bmhd.width;
X v_bit = 0;
X
X for (i=0;i<vert;i++)
X {
X s_vert = i/6;
X v_bit= i%6;
X for (j=0;j<horz;j++)
X {
X color = PixelArray[i][j];
X SixelLine[color][j][s_vert] |= (int)pow(2,v_bit);
X }
X }
X
X
X/********************************************************************
X
X Compress Sixels and write to file.
X
X********************************************************************/
X
X
X vert = bmhd.height/6;
X
X/* Write Sixel start code. */
X
X fprintf(outf,"%c;1;;q%c1;1;;\n",start_sixel,quote);
X
X/* Write color map. */
X
X for (color=0;color<num_colors;color++)
X {
X CMap[color].red = (CMap[color].red * 100)/255;
X CMap[color].green = (CMap[color].green * 100)/255;
X CMap[color].blue = (CMap[color].blue * 100)/255;
X fprintf(outf,"#%d;2;%d;%d;%d\n",color,
X CMap[color].red,CMap[color].green,CMap[color].blue);
X
X }
X fprintf(outf,"\n");
X
X
X/* Compress and write Sixels. */
X
X for (s_vert=0;s_vert <= vert;s_vert++)
X {
X for (color=0;color<num_colors;color++)
X {
X
X for (j=0;j<horz;j++)
X SixelLine[color][j][s_vert] += Sixel_base;
X i = 0;
X k = 0;
X while( i < horz )
X {
X ch = SixelLine[color][i][s_vert];
X l=i;
X
X while ((l < horz) && (ch == SixelLine[color][l][s_vert]))
X l++;
X rep_cnt = l - i;
X if (rep_cnt >= 5)
X {
X cnt_100 = rep_cnt/100;
X cnt_10 = (rep_cnt-(cnt_100 * 100))/10;
X cnt_1 = (rep_cnt-((cnt_100 * 100)+(cnt_10 * 10)));
X outline[k] = 33; /* Exclamation mark */
X outline[k+1] = cnt_100 + 48;
X outline[k+2] = cnt_10 + 48;
X outline[k+3] = cnt_1 + 48;
X outline[k+4] = SixelLine[color][l-1][s_vert];
X k += 5;
X i=l;
X }
X else
X {
X for (m=0;m<=(l-1)-i;m++)
X outline[k+m]=SixelLine[color][l-1][s_vert];
X k += (l-i);
X i=l;
X }
X }
X outline[k]=0;
X fprintf(outf,"#%d %s$\n",color,&outline);
X
X }
X fprintf(outf," - \n");
X }
X fprintf(outf,"%c\n",ST);
X close(outf);
X }
SHAR_EOF
echo "End of archive 1 (of 1)"
# if you want to concatenate archives, remove anything after this line
exit